<?php
/**
 * --------------------------------------------------------------------
 * MCore精简框架
 * 作者：阿枫，QQ：52037872，Email：support@mdeve.com
 * --------------------------------------------------------------------
 *
 * SVN revision information:
 * @version $Revision: 1 $:
 * @author  $Author: zy $:
 * @date      $Date: 2017-03-10 21:12:21 +0800 (星期五, 10 三月 2017) $:
 */

require dirname(__FILE__). "/drivers/abstract_user.php";

class _UserClass extends _user_interface {

    function __construct(){
        global $_M, $module_login;
        $module_islogin = false;

        if($_M->cfg["module_enable"]) module_insert_code('is_login');

        if(!$module_login) {
            $_M->is_login = $this->is_login();
        }
    }

    /**
     * 判断是否登录
     *
     * @return bool
     */
    public function is_login(){
        global $_M;
        $_M->is_login = false;
        if(!isset($_COOKIE['mc_auth'])) return false;
        list($uid, $username, $password, $save_status, $ip) = explode("\t", $_M->encrypt->authcode($_COOKIE['mc_auth'], 'DECODE'));
        $uid = intval($uid);
        $_M->db();
        $userinfo = $_M->db->get_row(array("table"=>"user", "where"=>"id={$uid}"));
        $ip = get_client_ip();
        $password = gzuncompress(base64_decode($password));
        if(!$uid || !strlen($username || !strlen($password) || !strlen($ip))) return false;
        // 根据用户ID获取用户资料
        if($userinfo===false) return false;
        // 判断用户名和密码是否正确
        if($username != $userinfo["user"]) return false;
        $pass_en = md5($userinfo["pass"]);
        $pass_en = substr($pass_en, 6, 9);
        $pass_en = md5($pass_en);
        // 判断cookie中存储的密码是否正确
        if($password != $pass_en) return false;
        // 判断最后一次登录的IP是否当前IP，如果是则正确，否则错误。
        $row = $_M->db->get_row(array("table"=>"user_logs", "where"=>"type='login' and uid={$uid} and ip='{$ip}'", "order"=>"time desc", "limit"=>"0,1"));
        if($row === false) return false;

        $userinfo["lastvisit"] = $row["time"];
        $userinfo["lastip"] = $row["ip"];
        $userinfo["uid"] = $userinfo["id"];
        // 更新用户信息
        $_M->db->update(array("lastactivity"=>date("Y-m-d H:i:s")), array("table"=>"session", "where"=>"uid={$uid}"));
        // 判断成功，修改cookie
        $pass_en = gzcompress($pass_en);
        $auth = $_M->encrypt->authcode($uid. "\t". $username. "\t". base64_encode($pass_en). "\t". $save_status. "\t". $ip, 'ENCODE');
        setcookie('mc_auth', $auth, time() + ($save_status ? 86400*90 : 7200), $_M->cfg['cookie']['cookie_path']);

        // 读取扩展资料
        $userinfo = $this->get_userinfo_by_uid($uid);

        $_M->userinfo = $userinfo;
        unset($userinfo);
        $_M->is_login = true;

        return true;
    }

    /**
     * 退出登陆
     *
     * @return bool
     */
    function logout(){
        global $_M;
        $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : "/";

        $_M->db();
        $data = array(
            "uid" => $_M->userinfo["id"],
            "type" => "logout",
            "ip" => get_client_ip(),
            "http_user_agent" => get_http_user_agent(),
            "status" => 1
        );
        $option = array("table" => "user_logs");
        $_M->db->insert($data, $option);

        $ip = get_client_ip();
        $_M->db->delete(array("table"=>"session", "where"=>"uid={$_M->userinfo["id"]} and ip='{$ip}'"));

        setcookie('mc_auth' , null , time()-86400 , "/");

        return true;
    }


    /**
     * 登陆操作
     *
     * @param $user 用户名
     * @param $pass 密码(md5)
     * @param string $referer 登陆后跳转地址
     * @param bool $save_status 是否保存登陆（不保存则退出浏览器失效，保存的话cookies保存一个月）
     * @return bool
     */
    function login($user, $pass, $referer = "/", $save_status = true){
        global $_M, $user, $pass, $pass_check_status, $row;

        // Check username and password
        if(!mb_strlen($user)) return "[0x01] 用户名没有填写或填写太短！";
        if(strlen($pass) != 32) return "[0x02] 密码格式错误！";
        if(stripos($user, "'")!==false || stripos($user, "%")!==false) return "[0x03] 用户名格式错误！";

        // save username, use cookies
        setcookie("lastuser", $user, time()+36400*999);

        // 从数据库获取用户资料
        $_M->db();
        ////////////////////////////////////////////
        // 从数据库存读取用户资料
        $option = array();
        $option["table"] = "user";
        if(valid_email($user)){
            $option["where"] = "email='{$user}'";
        }elseif(valid_mobile($user)){
            $option["where"] = "mobile='{$user}'";
        }else{
            $option["where"] = "user='{$user}'";
        }
        $row = $_M->db->get_row($option);

        ////////////////////////////////////////////
        $ip = get_client_ip();
        ////////////////////////////////////////////
        if(!is_array($row)) return "用户名不存在！";
        if($row["locked"]===true) return "用户已被冻结，请联系管理员！";
        // 检验密码
        require_once CORE_PATH. '/class/drivers/PasswordHash.php';
        $hasher = new PasswordHash(8, false);
        $pass_check_status = $hasher->CheckPassword($pass, $row["pass"]);

        if($_M->cfg["module_enable"]) module_insert_code('login_proc');
        /////////////////////////////////////////////
        // 日志数据
        $data = array(
            "uid" => $row["id"],
            "type" => "login",
            "ip" => $ip
        );
        $option = array("table" => "user_logs");
        /////////////////////////////////////////////
        if(!$pass_check_status){
            // 密码验证失败，记录日志
            $data["status"] = "0";
            $_M->db->insert($data, $option);
            return "密码错误！";
        }else{
            // 登录成功，记录日志
            $data["status"] = "1";
            $_M->db->insert($data, $option);
        }

        $_M->user();
        $_M->userinfo = $this->get_userinfo_by_uid($row["id"]);

        // 将登录信息记录在cookie
        $pass_en = md5($_M->userinfo["pass"]);
        $pass_en = substr($pass_en, 6, 9);
        $pass_en = md5($pass_en);
        $pass_en = gzcompress($pass_en);
        $auth = $_M->encrypt->authcode($_M->userinfo['id']."\t".$_M->userinfo['user']. "\t". base64_encode($pass_en). "\t". $save_status. "\t". $ip, 'ENCODE');
        // 如果允许保存状态则保存3个月，否则保存半小时
        setcookie('mc_auth', $auth, time() + ($save_status ? 86400*90 : 3600), "/");
        $_M->is_login = true;

        // 记录在线人数
        $data = array(
            "uid" => $_M->userinfo["id"],
            "user" => $_M->userinfo["user"],
            "uptime" => date("Y-m-d H:i:s"),
            "ip" => $ip,
            "http_user_agent" => get_http_user_agent(),
            "session_id" => session_id()
        );
        $_M->db->replace($data, array("table"=>"session", "field"=>"id", "where"=>"uid={$_M->userinfo["id"]} and ip='{$ip}'"));

        return true;
    }

    /**
     * 获取用户头像
     *
     * @param int $uid 如果$uid为空，返回自己的头像
     */
    function get_avatar($uid = 0){}


    /**
     * 获取用户详细资料，包括所有扩展字段
     *
     * @param int $uid 获取指定$uid用户资料
     */
    function get_userinfo_by_uid($uid){
        global $_M;
        if(!$uid) return false;
        if(!is_object($_M->db)) $_M->db();

        $row = $_M->db->get_row(array("table"=>"user", "where"=>"id={$uid}"));
        $meta = $_M->db->get_rows(array("table"=>"user_meta", "where"=>"uid={$uid}"));

        if(false === $row) return false;

        foreach($meta as $m){
            $row[$m["meta_key"]] = $m["meta_value"];
            $row[$m["meta_key"]. "_flag"] = $m["meta_flag"];
        }

        // 读取并合并用户的角色权限
        if(isset($row["role_ids"]) && strlen($row["role_ids"])){
            $permissions = $_M->db->get_rows(array("table"=>"user_role", "field"=>"permissions", "where"=>"id in({$row["role_ids"]})"));
            $permission = array();
            $p1 = $p2 = array();
            foreach($permissions as $p){
                $p["permissions"] = unserialize(DecodeZ($p["permissions"]));
                foreach ($p["permissions"] as $key=>$val){
                    if(is_array($val)) {
                        foreach($val as $k=>$v){
                            if(!isset($permission[$key][$k])){
                                $permission[$key][$k] = $v;
                            }else{
                                $permission[$key][$k] = max($permission[$key][$k], $v);
                            }
                        }
                    }else{
                        if($val) $permission[$key] = $val;
                    }
                }
            }
            $row["permissions"] = $permission;
        }else{
            $row["permissions"] = array();
        }

        return $row;
    }

    /**
     * 按用户名获取用户详细资料
     *
     * @param $username 用户名
     * @return array|bool 如果获取失败返回 false, 成功返回 array
     */
    function get_userinfo_by_username($username){
        global $_M;
        if(!strlen($username)) return false;
        if(!is_object($_M->db)) $_M->db();
        $userinfo = $_M->db->get_row(array("table"=>"user", "field"=>"id", "where"=>"username='{$username}'"));
        if(false===$userinfo) return false;
        return $this->mc_get_userinfo($userinfo["id"]);
    }


    /**
     * 设置用户扩展字段
     *
     * @param $uid
     * @param $meta_key
     * @param $meta_value
     * @param string $meta_flag
     * @return bool
     */
    function set_user_meta($uid, $meta_key, $meta_value, $meta_flag = ""){
        global $_M;
        if(!$uid){
            if(!isset($_M->userinfo["id"])) return false;
            $uid = $_M->userinfo["id"];
        }

        if(!is_object($_M->db)) $_M->db();
        $data = array("uid"=>$uid, "meta_key"=>$meta_key, "meta_value"=>$meta_value, "meta_flag"=>$meta_flag);
        $_M->db->replace($data, array("table"=>"user_meta", "where"=>"uid={$uid} and meta_key='{$meta_key}'"));
        return true;
    }

}